package com.yedean.factory;

import com.yedean.factory.config.BeanDefinition;
import com.yedean.factory.config.BeanFactoryPostProcessor;
import com.yedean.factory.io.DefaultResourceLoader;
import com.yedean.factory.io.Resource;
import com.yedean.factory.property.PropertyValue;
import com.yedean.factory.property.PropertyValues;
import com.yedean.factory.utils.StringValueResolver;

import java.util.Properties;

public class PropertyPlaceHolderConfiguer implements BeanFactoryPostProcessor {

    private static final String DEFAULT_PLACEHOLDER_PREFIX = "${";

    private static final String DEFAULT_PLACEHOLDER_SUFFIX = "}";

    private String location;

    public String getLocation() {
        return location;
    }

    public void setLocation(String location) {
        this.location = location;
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory factory) throws BeansException {

        try {
            //加载属性文件
            DefaultResourceLoader resourceLoader = new DefaultResourceLoader();
            Resource resource = resourceLoader.getResource(location);

            //占位符替换属性值
            Properties properties = new Properties();
            properties.load(resource.getInputStream());

            String[] definitionNames = factory.getBeanDefinitionNames();
            for (String definitionName : definitionNames) {
                
                BeanDefinition beanDefinition = factory.getBeanDefinition(definitionName);
                PropertyValues propertyValues = beanDefinition.getPropertyValues();
                
                for (PropertyValue propertyValue : propertyValues.getPropertyValue()) {
                    Object value = propertyValue.getValue();
                    if (!(value instanceof String)) {
                        continue;
                    }
                    resolvePlaceHolder((String) value,properties);
                }
            }

            // 向容器中添加字符串解析器，供解析@Value注解使用
            factory.addEmbeddedValueResolver(new PlaceholderResolvingStringValueResolver(properties));

        } catch (Exception e) {
            throw new BeansException("could not load properties!", e);
        }

    }


    private String resolvePlaceHolder(String value, Properties properties) {
        String strVal = value;
        StringBuilder builder = new StringBuilder(strVal);
        int startIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_PREFIX);
        int stopIdx = strVal.indexOf(DEFAULT_PLACEHOLDER_SUFFIX);
        if (startIdx != -1 && stopIdx != -1 && startIdx < stopIdx) {
            String propKey = strVal.substring(startIdx + 2, stopIdx);
            String propValue = properties.getProperty(propKey);
            builder.replace(startIdx, stopIdx + 1, propValue);
        }
        return builder.toString();
    }


    private class PlaceholderResolvingStringValueResolver implements StringValueResolver {

        private final Properties properties;

        private PlaceholderResolvingStringValueResolver(Properties properties) {
            this.properties = properties;
        }


        @Override
        public String resolveStringValue(String strVal) {
            return resolvePlaceHolder(strVal,properties);
        }
    }
}
